# coding=utf-8
from PIL import Image
from pprint import pformat
import os

class Tile(object):

    def _set_pattern(self, patternString):
        strs = patternString.strip().split()
        w = len(strs[0])
        h  = len(strs)
        self._pattern = [ [ strs[y][x] for y in range(h)] for x in range(w) ]
    def _get_pattern(self):
        return self._pattern

    pattern = property(_get_pattern, _set_pattern)

    def is_black(self):
        fm = self.fill_map
        for x in range(self.width):
            for y in range(self.height):
                if fm[x][y] and self.pattern[x][y] == '#':
                    return True
        return False

    @property
    def width(self):
        return len(self.pattern)

    @property
    def height(self):
        return len(self.pattern[0])

    @property
    def size(self):
        return self.width, self.height

    @property
    def fill_map(self):
        try:
            return self._fill_map
        except AttributeError:
            def opaque(x, y):
                iw, ih = self.image.size
                w,h = self.size
                pw, ph = float(iw)/w, float(ih)/h
                for i in range(int(pw*x), int(pw*(x+1))):
                    for j in range(int(ph*y), int(ph*(y+1))):
                        try:
                            if self.image.getpixel((i,j))[3] >= 128:
                                return True
                        except IndexError:
                            return True
                return False
            self._fill_map = [ 
                    [ opaque(x,y) for y in range(self.height)]
                    for x in range(self.width)  ]
            return self._fill_map

    def __init__(self, imageName="", groups=[], mapping={}, pattern='.', priority=0, anchor=(0,0), baseDir=".", **kwargs):
        self.imageName = imageName
        self.image = Image.open(os.path.join(baseDir, self.imageName))
        self.groups = groups
        self.mapping = mapping
        self.pattern = pattern
        self.priority = priority
        self.anchor = anchor
        self.mapping.update({'#':'#', '*':'*', '.':'.'})

    def matches(self, tileMap, xy):
        """ Zwraca, czy tile pasuje na tileMap na pozycji (x,y). """
        fm = self.fill_map
        for x in range(self.width):
            for y in range(self.height):
                p = self.mapping[self.pattern[x][y]]
                mxy = self.onMap(xy, (x,y))
                if not tileMap.is_there(p, mxy, (not fm[x][y] and (p in (".","*")))):
                	return False
                if fm[x][y] and tileMap.is_taken(mxy):
                    return False
        return True

    def onMap(self, mXY, xy):
        X, Y = mXY
        x, y = xy
        ax, ay = self.anchor
        return (X+x-ax, Y+y-ay)

    def use(self, tileMap, xy):
        """ Dodaje tile'a do tileMap na pozycji (x,y)."""
        fm = self.fill_map
        for x in range(self.width):
            for y in range(self.height):
                if fm[x][y]:
                	tileMap.set_field(self.groups, self.onMap(xy, (x,y)))

    def draw(self, image, xy, blockSize):
        """Rysuje tile'a na image."""
        bs = blockSize 
        X,Y = xy
        ax, ay = self.anchor
        box = (self.width*bs, self.height*bs)
        thumb = self.image.resize(box)
        thumb = thumb.convert("RGBA")
        image.paste(thumb, ((X-ax)*bs, (Y-ay)*bs), thumb)

    def __str__(self):
        return "<tile {0} {1}>".format(self.imageName, self.anchor)


class TileLoader(object):
    def __init__(self, tileset):
        """Tileset = nazwa katalogu z tile'ami"""
        from import_file import import_file
        self.tileset = import_file(os.path.join(tileset, 'tiles.py'))
        self.tileset_dir = tileset

    @property
    def dither(self):
        try:
            return self.tileset.dither
        except AttributeError:
            return 0

    @property
    def tiles(self):
        return [
                Tile(baseDir=self.tileset_dir, **tile)
                for tile in self.tileset.tiles
                ]
    @property
    def sorter(self):
        try:
            return self.tileset.sorter
        except AttributeError:
            return "bottomup"

        
